home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_08 / 2n08007b < prev    next >
Text File  |  1991-06-17  |  20KB  |  567 lines

  1. /*
  2.     A CUA compliant window class for data entry.
  3.     Uses dialog templates created with the resource compiler (rc),
  4.     or the OS/2 SDK screen painter (dlgbox).
  5.  
  6.     NB: Unlike a dialog box, a form has a true client window which
  7.     owns the data entry control windows.
  8. */
  9.  
  10. #include <stdlib.h> /* for calloc() and free() */
  11.  
  12. #define INCL_DOSRESOURCES /* For DosGetResource() */
  13. #define INCL_WIN
  14. #include <os2.h>
  15.  
  16. #include "form.h"
  17.  
  18. extern HAB hab; /* Under OS/2 1.2 you could use
  19.                    WinQueryAnchorBlock( HWND ) */
  20.  
  21. static MRESULT EXPENTRY wpFormFrame( HWND, USHORT, MPARAM, MPARAM );
  22.  
  23. HWND EXPENTRY FormLoad( HWND hwndParent, HWND hwndOwner, PFNWP pfnwp,
  24.                         HMODULE hmod, USHORT id, PVOID p )
  25. {
  26.     SEL sel;
  27.     HWND hwnd = NULL;
  28.  
  29.     if (!DosGetResource( hmod, RT_DIALOG, id, &sel ))
  30.     {
  31.         hwnd = FormCreate( hwndParent, hwndOwner, pfnwp,
  32.                            MAKEP( sel, 0 ), hmod, id, p );
  33.         DosFreeSeg( sel );
  34.     }
  35.     return hwnd;
  36. }
  37.  
  38. #define LINE_SIZE 8   /* Number of pels to move on scroll by line  */
  39. #define BORDER_SIZE 4 /* Whitespace to be left round edges of form */
  40. #define QWS_CXFORM  (2*sizeof(PVOID))
  41. #define QWS_CYFORM  (2*sizeof(PVOID)+sizeof(USHORT))
  42.  
  43. static void set_scrollbars( HWND hwnd,
  44.                             SHORT cxClient, SHORT cyClient );
  45.  
  46. HWND EXPENTRY FormCreate( HWND hwndParent, HWND hwndOwner,
  47.                           PFNWP pfnwp, PDLGTEMPLATE pDlgTemplate,
  48.                           HMODULE hmod, USHORT id, PVOID p )
  49. {
  50.     static BOOL fInitialized;
  51.     USHORT i;
  52.     HWND hwndFrame, hwnd;
  53.     HWND hctl=NULL; /* default control to start with focus */
  54.     FRAMECDATA fcdata; /* holds parameters used
  55.                           to create a frame window */
  56.     PSZ pszTitle;
  57.     HWND *pahwnd; /* pointer to array of control window handles */
  58.     POINTL aptl[2];
  59.     DLGTITEM *pDlgItem = &pDlgTemplate->adlgti[ 0 ];
  60.     USHORT cxClient, cyClient;
  61.     RECTL rclForm;
  62.  
  63.     if (!fInitialized)
  64.     {
  65.         fInitialized = TRUE;
  66.         #define CLASS_NAME "FORM" /* any unique name will do */
  67.         WinRegisterClass( hab, CLASS_NAME, wpForm, 0,
  68.                           2*sizeof(PVOID)+2*sizeof(USHORT) );
  69.     }
  70.     fcdata.cb = sizeof fcdata; /* initialization required by PM */
  71.     fcdata.flCreateFlags = 
  72.         *(PULONG)((PBYTE)pDlgTemplate +
  73.                          pDlgTemplate->adlgti[0].offCtlData)|
  74.         FCF_TITLEBAR | FCF_SYSMENU | FCF_SIZEBORDER |
  75.         FCF_HORZSCROLL | FCF_VERTSCROLL;
  76.     fcdata.hmodResources = hmod;
  77.     fcdata.idResources = id;
  78.  
  79.     pszTitle = (PSZ)pDlgTemplate + pDlgTemplate->adlgti[ 0 ].offText;
  80.     if (!*pszTitle)              /* if no text for title bar */
  81.         pszTitle = "(Untitled)"; /* provide something        */
  82.  
  83.     aptl[0].x = pDlgItem->x;  /* read size and position of form */
  84.     aptl[0].y = pDlgItem->y;  /* from first DLGTITEM structure  */
  85.     aptl[1].x = pDlgItem->cx;
  86.     aptl[1].y = pDlgItem->cy;
  87.  
  88.     /* convert from dialog units to pels */
  89.     WinMapDlgPoints( hwndParent, aptl, 2, TRUE );
  90.     cxClient = (USHORT)aptl[1].x;
  91.     cyClient = (USHORT)aptl[1].y;
  92.     
  93.     /* inflate the frame window to accomodate controls around the form */
  94.     aptl[0].x -= WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );
  95.     aptl[0].y -= WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );
  96.     aptl[0].y -= WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL );
  97.  
  98.     aptl[1].x += 2 * WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );
  99.     aptl[1].x += WinQuerySysValue( HWND_DESKTOP, SV_CXVSCROLL );
  100.  
  101.     aptl[1].y += 2 * WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );
  102.     aptl[1].y += WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR );
  103.     aptl[1].y += WinQuerySysValue( HWND_DESKTOP, SV_CYHSCROLL );
  104.  
  105.     if (fcdata.flCreateFlags & FCF_MENU)
  106.         aptl[1].y += WinQuerySysValue( HWND_DESKTOP, SV_CYMENU );
  107.     
  108.     hwndFrame = WinCreateWindow( hwndParent, WC_FRAME, pszTitle,
  109.                     0, 0, 0, 0, 0, hwndOwner, HWND_TOP, id,
  110.                     &fcdata, 0 );
  111.     if (!hwndFrame)
  112.     {
  113.         /* display PM error message */
  114.         ErrorInfoMessageBox( hab, hwndParent, "Form creation error" );
  115.         return NULL;
  116.     }
  117.     hwnd = WinCreateWindow( hwndFrame, CLASS_NAME, 0, 0, 0, 0, 0, 0, 0,
  118.                             HWND_TOP, FID_CLIENT, 0, 0 );
  119.  
  120.     WinSetWindowPos( hwndFrame, HWND_TOP, 
  121.                      (SHORT)aptl[0].x, (SHORT)aptl[0].y, 
  122.                      (SHORT)aptl[1].x, (SHORT)aptl[1].y,
  123.                      SWP_SIZE | SWP_MOVE );
  124.  
  125.     pahwnd = (HWND*)calloc( pDlgTemplate->adlgti[ 0 ].cChildren+1, 
  126.                             sizeof(HWND) );
  127.     WinSetWindowPtr( hwnd, QWL_USER+sizeof(PVOID), pahwnd );
  128.  
  129.     rclForm.xLeft = rclForm.xRight =
  130.         rclForm.yBottom = rclForm.yTop = 0;
  131.  
  132.     /* create the child control windows */
  133.     for (i = 1; i <= pDlgTemplate->adlgti[ 0 ].cChildren; i++)
  134.     {
  135.         pDlgItem = &pDlgTemplate->adlgti[ i ];
  136.  
  137.         aptl[0].x = pDlgItem->x;
  138.         aptl[0].y = pDlgItem->y;
  139.         aptl[1].x = pDlgItem->cx;
  140.         aptl[1].y = pDlgItem->cy;
  141.  
  142.         WinMapDlgPoints( hwnd, aptl, 2, TRUE/*Convert du to pels*/ );
  143.  
  144.         pahwnd[ i-1 ] = WinCreateWindow( hwnd, 
  145.             pDlgItem->offClassName < 10 ?
  146.                 /* Stock class or user defined? */
  147.                 (PSZ)(0xFFFF0000 | (LONG)pDlgItem->offClassName):
  148.                 (PSZ)pDlgTemplate + pDlgItem->offClassName,
  149.             (PSZ)pDlgTemplate + pDlgItem->offText,
  150.             pDlgItem->flStyle,
  151.             (SHORT)aptl[0].x, (SHORT)aptl[0].y, 
  152.             (SHORT)aptl[1].x, (SHORT)aptl[1].y, hwnd, HWND_TOP,
  153.             pDlgItem->id, 0, 0 );
  154.  
  155.         /* record first tabstop item - will receive default focus */
  156.         if (!hctl && pDlgItem->flStyle & WS_TABSTOP)
  157.             hctl = pahwnd[ i-1 ];
  158.  
  159.         rclForm.xLeft =   min( rclForm.xLeft,   aptl[0].x );
  160.         rclForm.yBottom = min( rclForm.yBottom, aptl[0].y );
  161.         rclForm.xRight =  max( rclForm.xRight,  aptl[0].x+aptl[1].x );
  162.         rclForm.yTop =    max( rclForm.yTop,    aptl[0].y+aptl[1].y );
  163.     }
  164.     WinSetWindowUShort( hwnd, QWS_CXFORM,
  165.                         (USHORT)(rclForm.xRight-rclForm.xLeft+
  166.                                                      2*BORDER_SIZE) );
  167.     WinSetWindowUShort( hwnd, QWS_CYFORM,
  168.                         (USHORT)(rclForm.yTop-rclForm.yBottom+
  169.                                                      2*BORDER_SIZE) );
  170.     WinSubclassWindow( hwndFrame, wpFormFrame );/* for scrollbars */
  171.     WinSubclassWindow( hwnd, pfnwp/*user defined window proc*/ );
  172.  
  173.     set_scrollbars( hwnd, cxClient, cyClient );
  174.  
  175.     if (!WinSendMsg( hwnd, WM_INITDLG, hctl, p ))
  176.         WinSetFocus( HWND_DESKTOP, hctl );
  177.  
  178.     if (pDlgItem->flStyle & WS_VISIBLE)
  179.         WinShowWindow( hwndFrame, TRUE );
  180.  
  181.     return hwnd;
  182. }
  183.  
  184. static MRESULT EXPENTRY wpFormFrame( HWND hwnd, USHORT msg,
  185.                                      MPARAM mp1, MPARAM mp2 )
  186. {
  187.     USHORT usPos, usMin, usMax;
  188.     SHORT sMove;
  189.     HWND hctl;
  190.     MRESULT mr;
  191.     RECTL rclUpdate;
  192.  
  193.     switch( msg )
  194.     {
  195.     case WM_HSCROLL:
  196.     case WM_VSCROLL:
  197.         hctl = WinWindowFromID( hwnd, SHORT1FROMMP(mp1) );
  198.         mr = WinSendMsg( hctl, SBM_QUERYRANGE, 0L, 0L );
  199.         usMin = SHORT1FROMMR( mr );
  200.         usMax = SHORT2FROMMR( mr );
  201.         usPos = SHORT1FROMMR( WinSendMsg( hctl, SBM_QUERYPOS, 0L, 0L ) );
  202.  
  203. #if !defined(min)
  204. #define max(a,b)        (((a) > (b)) ? (a) : (b))
  205. #define min(a,b)        (((a) < (b)) ? (a) : (b))
  206. #endif
  207.         switch (SHORT2FROMMP(mp2))
  208.         {
  209.         case SB_LINELEFT: /* #defined same as SB_LINEUP */
  210.             sMove = -min( LINE_SIZE, usPos-usMin );
  211.             break;
  212.         case SB_PAGELEFT: /* #defined same as SB_PAGEUP */
  213.             sMove = -min( 8*LINE_SIZE, usPos-usMin );
  214.             break;
  215.         case SB_LINERIGHT:/* #defined same as SB_LINEDOWN */
  216.             sMove = +min( LINE_SIZE, usMax-usPos );
  217.             break;
  218.         case SB_PAGERIGHT:/* #defined same as SB_PAGEDOWN */
  219.